package com.zhuiyun.project.api.system.user.controller;

import com.wf.captcha.base.Captcha;
import com.zhuiyun.project.annotation.OptLog;
import com.zhuiyun.project.api.system.role.entity.SysRole;
import com.zhuiyun.project.api.system.role.service.SysRoleService;
import com.zhuiyun.project.api.system.user.entity.SysUser;
import com.zhuiyun.project.api.system.user.model.SysUserModel;
import com.zhuiyun.project.api.system.user.service.SysUserService;
import com.zhuiyun.project.common.controller.BaseController;
import com.zhuiyun.project.common.errorCode.CommonException;
import com.zhuiyun.project.common.errorCode.EmErrorCode;
import com.zhuiyun.project.utils.*;
import com.zhuiyun.project.utils.constants.CommonConstants;
import com.zhuiyun.project.common.response.CommonResult;
import com.zhuiyun.project.utils.pageUtil.PageRequest;
import com.zhuiyun.project.utils.validator.ValidatorUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName SysUserController
 * @Description 用户管理 用于系统的登录  /login 默认登录地址 logout 登出地址
 * @Author zcy
 * @Date 2023/3/28 14:17
 **/
@RestController
@Api(tags = "用户管理")
@RequestMapping("/sysUser")
@Slf4j
@CrossOrigin
public class SysUserController extends BaseController {

    @Autowired
    SysUserService sysUserService;

    @Autowired
    SysRoleService sysRoleService;

    @GetMapping("/getUserByToken")
    public CommonResult getUserByToken(String token){
        try{
            SysUser sysUser = (SysUser) RedisUtil.get(token);
            return CommonResult.ok(sysUser);
        }catch (Exception e){
            e.printStackTrace();
            return CommonResult.ok(e);
        }
    }

    @GetMapping("/getListByLoginName")
    public CommonResult getListByLoginName(String loginName){
        return CommonResult.ok(sysUserService.getUserByLoginName(loginName));
    }
    /**
     * 保存用户
     * @param sysUserModel
     * @return
     */
    @PostMapping("/saveUser")
    @ApiOperation(value = "用户管理的新增方法")
    @OptLog(modular = "用户管理", type = CommonConstants.ADD, describe = "新增用户")
    public CommonResult saveUser(@RequestBody SysUserModel sysUserModel) throws CommonException {
        log.info("新增用户");
        // 验证参数的规范性
        if(ValidatorUtil.ValidationObject(sysUserModel)){
            SysUser sysUser = new SysUser();
            // sysUserModel 对象拷贝成 sysUser
            BeanUtils.copy(sysUserModel, sysUser);
            sysUser.setCreateBy(getLoginName());
            sysUser.setCreateTime(new Date());
            sysUser.setDelFlag("0");
            sysUser.setStatus("0");
            sysUser.setAvatarId("2");
            int i = sysUserService.saveUser(sysUser);
            if(i>0){
                return CommonResult.ok(EmErrorCode.SAVE_OK);
            }else{
                return CommonResult.ok(EmErrorCode.SAVE_ERROR);
            }
        }else{
            return CommonResult.ok(EmErrorCode.SAVE_ERROR);
        }
    }
    /**
     * 修改用户信息
     * @param sysUserModel
     * @return
     */
    @PutMapping("/updateUser")
    @ApiOperation(value = "用户管理的修改方法")
    @OptLog(modular = "用户管理", type = CommonConstants.UPDATE, describe = "修改用户")
    public CommonResult updateUser(@RequestBody SysUserModel sysUserModel) throws CommonException {
        log.info("修改用户");
        return sysUserService.updateUser(sysUserModel);
    }
    /**
     * 删除用户信息
     * @param id
     * @return
     */
    @DeleteMapping("/delUserById")
    @ApiOperation(value = "用户管理的删除方法")
    @OptLog(modular = "用户管理", type = CommonConstants.DELETE, describe = "删除用户")
    public CommonResult delUserById(Integer id) throws CommonException {
        log.info("删除用户信息");
        return sysUserService.delUserById(id);
    }
    /**
     * 查询用户信息
     * @param sysUserModel
     * @return
     */
    @GetMapping("/getUserByPage")
    @ApiOperation(value = "用户管理的分页查询方法")
    @OptLog(modular = "用户管理", type = CommonConstants.SELECT, describe = "分页查询")
    public CommonResult getUserByPage(SysUserModel sysUserModel, PageRequest pageRequest) throws CommonException {
        log.info("分页查询");
        return sysUserService.getUserByPage(sysUserModel,pageRequest);
    }

    /**
     * @Author songyongcheng
     * 获取验证麻(返回的img属性可以直接放到图片得src中)登陆的时候需要携带code到(前端取data中的imgCode)
     * @Date 2023/3/30 14:10
     * @Return
     */
    @GetMapping("/code")
    @ApiOperation(value = "获取验证码")
    public CommonResult getCode(){
        // 调用验证码生成工具类
        Captcha captcha = CodeUtils.switchCaptcha();
        String captchaValue = captcha.text();
        String key = CommonConstants.CACHE_USER_PASSWORD_CODE+captchaValue;
        // 保存Redis中过期时间120秒
        RedisUtil.set(key,1,120);
        // 验证码信息
        return CommonResult.ok(captcha.toBase64());
    }

    /**
    * @Author hbx
    * @Description 获取用户列表分页
    * @Date 2023/6/22 10:22
    * @param pageRequest
    * @param user
    */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @ApiOperation(value = "用户详情分页查询")
    @OptLog(modular = "用户详情管理" , type =CommonConstants.SELECT, describe = "用户详情分页查询")
    @GetMapping("/list")
    public CommonResult list(PageRequest pageRequest,SysUser user)
    {
        return CommonResult.ok(sysUserService.selectUserList(pageRequest,user));
    }

    /**
    * @Author hbx
    * @Description 新增用户
    * @Date 2023/6/22 10:24
    * @param user
    */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @ApiOperation(value = "新增用户")
    @OptLog(modular = "用户详情管理", type = CommonConstants.ADD , describe = "新增用户")
    @PostMapping
    public CommonResult add(@Validated @RequestBody SysUser user)
    {
        // 校验用户名称是否唯一
        if (!sysUserService.checkLoginNameUnique(user))
        {
            return CommonResult.error("新增用户'" + user.getLoginName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhone()) && !sysUserService.checkPhoneUnique(user))
        {
            return CommonResult.error("新增用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !sysUserService.checkEmailUnique(user))
        {
            return CommonResult.error("新增用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getLoginName());
        user.setDelFlag("0");
        user.setStatus("0");
        user.setAvatarId("2");
        user.setSex("2");
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return CommonResult.ok(sysUserService.insertUser(user));
    }

    /**
    * @Author hbx
    * @Description 根据用户编号获取详细信息
    * @Date 2023/6/22 10:25
    * @param id
    */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @ApiOperation(value = "根据用户编号获取信息")
    @OptLog(modular = "用户详情管理", type = CommonConstants.SELECT ,describe = "根据用户编号获取信息")
    @GetMapping(value = { "/", "/{userId}" })
    public CommonResult getInfo(@PathVariable(value = "userId", required = false) Integer id)
    {
        sysUserService.checkUserDataScope(id);
        List<SysRole> roles = sysRoleService.selectRoleAll();
        HashMap<String,Object> map = new HashMap<>();
        map.put("roles", SysUser.isAdmin(id) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        if (StringUtils.isNotNull(id))
        {
            SysUser sysUser = sysUserService.selectUserById(id);
            map.put("sysUser", sysUser);
            map.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
        }
        return CommonResult.ok(map);
    }

    /**
    * @Author hbx
    * @Description 修改用户
    * @Date 2023/6/22 10:36
    * @param user
    */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @ApiOperation(value = "修改用户")
    @OptLog(modular = "用户详情管理", type = CommonConstants.UPDATE ,describe = "修改用户")
    @PutMapping
    public CommonResult edit(@Validated @RequestBody SysUser user)
    {
        sysUserService.checkUserAllowed(user);
        sysUserService.checkUserDataScope(user.getId());
        if (!sysUserService.checkLoginNameUnique(user))
        {
            return CommonResult.error("修改用户'" + user.getLoginName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhone()) && !sysUserService.checkPhoneUnique(user))
        {
            return CommonResult.error("修改用户'" + user.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !sysUserService.checkEmailUnique(user))
        {
            return CommonResult.error("修改用户'" + user.getLoginName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(getLoginName());
        return CommonResult.ok(sysUserService.updateUsers(user));
    }


    /**
    * @Author hbx
    * @Description 删除用户
    * @Date 2023/6/22 10:38
    * @param userIds
    */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @ApiOperation(value = "删除用户")
    @OptLog(modular = "用户详细管理", type = CommonConstants.DELETE, describe = "删除用户")
    @DeleteMapping("/{userIds}")
    public CommonResult remove(@PathVariable Integer[] userIds) {
        if (ArrayUtils.contains(userIds, getUserId())) {
            return CommonResult.error("当前用户不能删除");
        }
        return sysUserService.deleteUserByIds(userIds);
    }

    /**
    * @Author hbx
    * @Description 状态修改
    * @Date 2023/6/22 10:40
    * @param user
    */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @ApiOperation(value = "修改用户状态")
    @OptLog(modular = "用户详细管理", type = CommonConstants.UPDATE , describe = "修改用户状态")
    @PutMapping("/changeStatus")
    public CommonResult changeStatus(@RequestBody SysUser user)
    {
        sysUserService.checkUserAllowed(user);
        sysUserService.checkUserDataScope(user.getId());
//        user.setUpdateBy(getUsername());
        return CommonResult.ok(sysUserService.updateUserStatus(user));
    }
}
